﻿using System;
using System.Xml;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.Xml.Linq;
using Ccit.SysPlat.Log;

namespace Ccit.Utils
{
    /// <summary>
    /// 系统配置文件操作工具类
    /// </summary>
    public class ConfigLib
    {
        #region init error log interface
        private static ILog _logInterface = null;
        private const string _funcPageName = "ConfigLib类接口";
        private static string _SYS_CONFIG = "Config/SysConfig.xml";  //default read system config file
        #endregion
      

        #region public static interface
        /// <summary>
        /// 获取配置文件中节点配置值
        /// </summary>
        /// <param name="nodeName">节点名称</param>
        /// <param name="enValueType">要获取的节点值类型</param>
        /// <returns></returns>
        public static string GetAttribute(string nodeName, eValueType enValueType)
        {            
            string sRetValue = string.Empty;
            XmlDocument oDom = new XmlDocument();
            bool bLoad = loadConfigFile(_SYS_CONFIG, ref oDom);
            if (!bLoad) return sRetValue;

            XmlNode oRoot = oDom.DocumentElement;
            XmlNode xmlNode = (null != oRoot) ? oRoot.SelectSingleNode(nodeName) : null;
            if (null == xmlNode) return sRetValue;

            switch (enValueType)
            {
                case eValueType.TEXT:
                    sRetValue = xmlNode.InnerText;
                    break;
                case eValueType.INNERXML:
                    sRetValue = xmlNode.InnerXml;
                    break;
                case eValueType.OUTERXML:
                    sRetValue = xmlNode.OuterXml;
                    break;
                default:
                    break;
            }

            oDom = null;
            return sRetValue;

        }

        /// <summary>
        /// 获取节点属性值
        /// </summary>
        /// <param name="enNodeType">节点类型枚举</param>
        /// <returns></returns>
        public static string GetAttribute(eNodeType enNodeType)
        {
            string sRetValue = string.Empty;
            switch (enNodeType)
            {
                case eNodeType.CSS:
                    XmlDocument oDom = new XmlDocument();
                    bool bLoad = loadConfigFile(_SYS_CONFIG, ref oDom);
                    if (!bLoad) return sRetValue;

                    XmlNode oRoot = oDom.DocumentElement;
                    if (null == oRoot) return sRetValue;
                    sRetValue = oRoot.SelectSingleNode("CCIT_APPSTYLE").InnerText;
                    oDom = null;
                    break;
                case eNodeType.MULTIORGAN:
                    sRetValue = GetAttribute("CCIT_SYSTEM/CCIT_MULTIORGAN", eValueType.TEXT);
                    break;
                case eNodeType.MULTIDEPT:
                    sRetValue = GetAttribute("CCIT_SYSTEM/CCIT_MULTIDEPT", eValueType.TEXT);
                    break;
                case eNodeType.INDENTIFYUSER:
                    sRetValue = GetAttribute("CCIT_SYSTEM/CCIT_IDENTIFYUSER", eValueType.TEXT);
                    break;
                case eNodeType.SYSMENUOPER:
                    sRetValue = GetAttribute("CCIT_MENU/CCIT_SYSOPER", eValueType.TEXT);
                    break;
                case eNodeType.MENU_MODNUMBER:
                    sRetValue = GetAttribute("CCIT_MENU/CCIT_MODNUMBER", eValueType.TEXT);
                    break;
                case eNodeType.MENU_IMGNUMBER:
                    sRetValue = GetAttribute("CCIT_MENU/CCIT_IMGNUMBER", eValueType.TEXT);
                    break;
                case eNodeType.MENU_SELMODE:
                    sRetValue = GetAttribute("CCIT_MENU/CCIT_SELMODE", eValueType.TEXT);
                    break;
                case eNodeType.PDUCODE:
                    sRetValue = GetAttribute("CCIT_PDUIDENTIFY/CCIT_PDUCODE", eValueType.TEXT);
                    break;
                case eNodeType.PDUNUMBER:
                    sRetValue = GetAttribute("CCIT_PDUIDENTIFY/CCIT_PDUNUMBER", eValueType.TEXT);
                    break;
                case eNodeType.MOBILEURI:
                    sRetValue = GetAttribute("CCIT_MOBILE/CCIT_URI", eValueType.TEXT);
                    break;
                case eNodeType.MOBILEKEY:
                    sRetValue = GetAttribute("CCIT_MOBILE/CCIT_KEY", eValueType.TEXT);
                    break;
                case eNodeType.SYSDICTOPER:
                    sRetValue = GetAttribute("CCIT_SYSTEM/CCIT_DICTOPER", eValueType.TEXT);
                    break;
                default:

                    break;
            }
            
            return sRetValue;
        }


        /// <summary>
        /// 获取产品版本标识信息
        /// (由于在Application启动时要调用到该接口,而此时还没有获取产品数据库类型，因此不能调用工厂类)
        /// </summary>
        /// <param name="pduCode"></param>
        /// <param name="pduNumber"></param>
        /// <returns></returns>
        public static void GetPduIdentify(ref string pduCode, ref string pduNumber)
        {
            pduCode = string.Empty;
            pduNumber = string.Empty;
                        
            string relPath = RequestContext.GetRelativelyPath();
            string fullPath = relPath + _SYS_CONFIG;
            string absPath = HttpContext.Current.Server.MapPath(fullPath);

            XmlDocument oDom = new XmlDocument();
            try {
                if (!File.Exists(absPath))
                    throw new Exception("无法找到系统配置文件，请确认文件是否存在后重新启动IIS站点!");
                               
                oDom.Load(absPath);
                XmlNode oRoot = oDom.DocumentElement;
                XmlNode codeNode = (null != oRoot) ? oRoot.SelectSingleNode("CCIT_PDUIDENTIFY/CCIT_PDUCODE") : null;
                XmlNode numberNode = (null != oRoot) ? oRoot.SelectSingleNode("CCIT_PDUIDENTIFY/CCIT_PDUNUMBER") : null;
                pduCode = (null != codeNode) ? codeNode.InnerText : string.Empty;
                pduNumber = (null != numberNode) ? numberNode.InnerText : string.Empty;

                numberNode = null;
                codeNode = null;
                oRoot = null;

                oDom = null;

            }
            catch (XmlException ex)
            {
                throw new Exception("系统配置文件格式不正确!");
            }
            catch (Exception ex)
            {
                throw new Exception("系统配置文件格式不正确!");
            }
            
        }

        private static bool loadConfigFile(string fileName, ref XmlDocument oDom)
        {
            #region init 日志接口
            if (null == _logInterface)
                _logInterface = Factory.CreateObject(MsErrLog.assemblyName, MsErrLog.className,
                                                     ImportComponentType.DotNetDll, null) as ILog;
            #endregion

            bool bLoad = false;
            string relPath = RequestContext.GetRelativelyPath();
            string fullPath = relPath + fileName;
            string absPath = HttpContext.Current.Server.MapPath(fullPath);

            try
            {
                if (!File.Exists(absPath))
                    throw new Exception("System Config File Is Not Founded!");

                if (null == oDom) oDom = new XmlDocument();
                oDom.Load(absPath);
                bLoad = true;
            }
            catch (XmlException ex)
            {
                MsErrLog msErrorLog = new MsErrLog
                {
                    funcPageName = _funcPageName,
                    errMsg = ex.Message,
                    codeTrack = ex.StackTrace,
                    errClassCode = "003", //XML 加载异常
                    paramInfo = "配置文件:【" + absPath + "】不是正确的XML文档格式"
                };

                _logInterface.WriteErrorLog(msErrorLog);
                msErrorLog = null;
            }
            catch (Exception ex)
            {
                MsErrLog msErrorLog = new MsErrLog
                {
                    funcPageName = _funcPageName,
                    errMsg = ex.Message,
                    codeTrack = ex.StackTrace,
                    errClassCode = "004", //读取系统配置文件异常
                    paramInfo = "文件路径:【" + absPath + "】"
                };

                _logInterface.WriteErrorLog(msErrorLog);
                msErrorLog = null;
            }

            return bLoad;
            
        }
        #endregion

    }

    /// <summary>
    /// 配置文件类型枚举
    /// </summary>
    public enum eConfigFileType
    {
        /// <summary>
        /// 系统配置文件
        /// </summary>
        SYSTEM = 0,   // system config file
        /// <summary>
        /// 工作流配置文件
        /// </summary>
        WORKFLOW = 1  // workflow config file
    }

    /// <summary>
    /// 节点值类型枚举
    /// </summary>
    public enum eValueType
    {
        /// <summary>
        /// 节点值
        /// </summary>
        TEXT = 1,
        /// <summary>
        /// 节点全部 XML
        /// </summary>
        OUTERXML = 2,
        /// <summary>
        /// 节点内 XML
        /// </summary>
        INNERXML = 3
    }

    /// <summary>
    /// system config file's node Type enum
    /// </summary>
    public enum eNodeType
    {
        /// <summary>
        /// 系统样式
        /// </summary>
        CSS = 1,
        /// <summary>
        /// 多机构
        /// </summary>
        MULTIORGAN = 2,
        /// <summary>
        /// 多部门、职位
        /// </summary>
        MULTIDEPT = 3,
        /// <summary>
        /// 身份认证锁
        /// </summary>
        INDENTIFYUSER = 4,
        /// <summary>
        /// 系统菜单操作权限
        /// </summary>
        SYSMENUOPER = 5,
        /// <summary>
        /// 菜单模块数配置
        /// </summary>
        MENU_MODNUMBER = 6,
        /// <summary>
        /// 菜单图片显示数量配置
        /// </summary>
        MENU_IMGNUMBER = 7,
        /// <summary>
        /// 页面加载显示页面模式
        /// </summary>
        MENU_SELMODE = 8,
        /// <summary>
        /// 产品代码
        /// </summary>
        PDUCODE = 9,
        /// <summary>
        /// 产品号
        /// </summary>
        PDUNUMBER = 10,
        /// <summary>
        /// 手机短信平台地址 (for china mobile)
        /// </summary>
        MOBILEURI = 11,
        /// <summary>
        /// 手机短信平台密钥 (for china mobile)
        /// </summary>
        MOBILEKEY = 12,
        /// <summary>
        /// 系统字典操作权限开关(-999开启，其余关闭)
        /// </summary>
        SYSDICTOPER = 13
    }
   
}
